package com.wst.system.controller.template;

import com.wst.system.config.SecretKeyComponent;
import com.wst.system.config.cache.SysCache;
import com.wst.system.config.cache.SysCacheServer;
import com.wst.system.security.IsSecurity;
import com.wst.system.server.service.SysUserTokenService;
import com.wst.system.util.CookieUtils;
import com.wst.system.util.RandomCodeGenerator;
import com.wst.system.util.RandomNumber;
import com.wst.system.util.RandomStringGenerator;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/lay")
public class IndexController {

    @Autowired
    private SecretKeyComponent secretKeyComponent;

    @Autowired
    private SysCacheServer sysCacheServer;

    @GetMapping("/hello")
    public String hello(@RequestParam(name = "name", defaultValue = "World") String name, Map<String,Object> map) {
        System.out.println("111111111111111111");
        // 将数据传递给模板
        map.put("name", name);
        // 返回模板名称（不需要加后缀）
        return "page/hello";
    }

    @ApiOperation("登录加密模块")
    @IsSecurity(isSecurity = false)
    @GetMapping(value = "/secrypt-dynamic-script.js", produces = "application/javascript")
    public String dynamicLoginScript(HttpServletResponse response, Map<String,Object> map) {
        response.setContentType("application/javascript;charset=UTF-8");
        String randomString = RandomStringGenerator.generateRandomString(100); // 生成长度为 20 的随机字符串
        char[] randomCharArray = RandomStringGenerator.convertStringToCharArray(randomString);
        String sessionId=secretKeyComponent.getSessionId(); //获取随机会话id
        String secretKey= secretKeyComponent.getSecretKey(sessionId); //获取随机秘钥
        secretKey=Base64.getEncoder().encodeToString(secretKey.getBytes(StandardCharsets.UTF_8));
        sessionId=Base64.getEncoder().encodeToString(sessionId.getBytes(StandardCharsets.UTF_8));
        // 记录插入的下标
        List<Integer> insertedIndices_secretKey = new ArrayList<>();
        char[] newArraySecretKey = RandomStringGenerator.insertStringRandomly(randomCharArray, secretKey, insertedIndices_secretKey);
        List<Character> charListSecretKey = new java.util.ArrayList<>();
        for (char c : newArraySecretKey) {
            charListSecretKey.add(c);
        }
        List<Integer> insertedIndices_sessionId = new ArrayList<>();
        char[] newArraySessionId = RandomStringGenerator.insertStringRandomly(randomCharArray, sessionId, insertedIndices_sessionId);
        List<Character> charListSessionId = new java.util.ArrayList<>();
        for (char c : newArraySessionId) {
            charListSessionId.add(c);
        }

        String captchaSid=String.valueOf(RandomNumber.generateRandomNumber(8))+String.valueOf(RandomNumber.generateRandomNumber(8));
        String captchaCode= RandomCodeGenerator.generateRandomCode(4);
        sysCacheServer.put(captchaSid,captchaCode);

        System.out.println("code:"+captchaCode+" :: "+captchaSid);
        captchaSid=Base64.getEncoder().encodeToString(captchaSid.getBytes(StandardCharsets.UTF_8));
        captchaCode=Base64.getEncoder().encodeToString(captchaCode.getBytes(StandardCharsets.UTF_8));

        List<Integer> insertedIndices_captchaSid = new ArrayList<>();
        char[] newArrayCaptchaSid = RandomStringGenerator.insertStringRandomly(randomCharArray, captchaSid, insertedIndices_captchaSid);
        List<Character> charListCaptchaSid = new java.util.ArrayList<>();
        for (char c : newArrayCaptchaSid) {
            charListCaptchaSid.add(c);
        }
        List<Integer> insertedIndices_captchaCode = new ArrayList<>();
        char[] newArrayCaptchaCode = RandomStringGenerator.insertStringRandomly(randomCharArray, captchaCode, insertedIndices_captchaCode);
        List<Character> charListCaptchaCode = new java.util.ArrayList<>();
        for (char c : newArrayCaptchaCode) {
            charListCaptchaCode.add(c);
        }
        map.put("islogin",true);
        map.put("isDecrypt",false);
        map.put("charListCaptchaCode",charListCaptchaCode);
        map.put("insertedIndicesCaptchaCode",insertedIndices_captchaCode);
        map.put("charListCaptchaSid",charListCaptchaSid);
        map.put("insertedIndicesCaptchaSid",insertedIndices_captchaSid);
        map.put("charListSecretKey", charListSecretKey);
        map.put("charListSessionId",charListSessionId);
        map.put("insertedIndicesSecretKey", insertedIndices_secretKey);
        map.put("insertedIndicesSessionId", insertedIndices_sessionId);
        return "js/secrypt_model";
    }

    /**
     * 每请求一次，都需要重新请求
     * @param response
     * @param map
     * @return
     */
    @ApiOperation("重要接口加密模块")
    @IsSecurity(isSecurity = false)
    @GetMapping(value = "/secrypt-script.js", produces = "application/javascript")
    public String dynamicScript(HttpServletResponse response, Map<String,Object> map) {
        response.setContentType("application/javascript;charset=UTF-8");
        String randomString = RandomStringGenerator.generateRandomString(100); // 生成长度为 20 的随机字符串
        char[] randomCharArray = RandomStringGenerator.convertStringToCharArray(randomString);
        String sessionId=secretKeyComponent.getSessionId(); //获取随机会话id
        String secretKey= secretKeyComponent.getSecretKey(sessionId); //获取随机秘钥
        String sessionIdStr=sessionId;
        secretKey=Base64.getEncoder().encodeToString(secretKey.getBytes(StandardCharsets.UTF_8));
        sessionId=Base64.getEncoder().encodeToString(sessionId.getBytes(StandardCharsets.UTF_8));
        // 记录插入的下标
        List<Integer> insertedIndices_secretKey = new ArrayList<>();
        char[] newArraySecretKey = RandomStringGenerator.insertStringRandomly(randomCharArray, secretKey, insertedIndices_secretKey);
        List<Character> charListSecretKey = new java.util.ArrayList<>();
        for (char c : newArraySecretKey) {
            charListSecretKey.add(c);
        }
        List<Integer> insertedIndices_sessionId = new ArrayList<>();
        char[] newArraySessionId = RandomStringGenerator.insertStringRandomly(randomCharArray, sessionId, insertedIndices_sessionId);
        List<Character> charListSessionId = new java.util.ArrayList<>();
        for (char c : newArraySessionId) {
            charListSessionId.add(c);
        }
        //生成请求id,防止重复请求
        String reqId=String.valueOf(RandomNumber.generateRandomNumber(8))+String.valueOf(RandomNumber.generateRandomNumber(8));
        sysCacheServer.putOnce(reqId,sessionIdStr);
        reqId=Base64.getEncoder().encodeToString(reqId.getBytes(StandardCharsets.UTF_8));
        List<Integer> insertedIndices_reqId = new ArrayList<>();
        char[] newArrayReqId = RandomStringGenerator.insertStringRandomly(randomCharArray, reqId, insertedIndices_reqId);
        List<Character> charListReqId = new java.util.ArrayList<>();
        for (char c : newArrayReqId) {
            charListReqId.add(c);
        }
        map.put("islogin",false);
        map.put("isDecrypt",true);
        map.put("charListSecretKey", charListSecretKey);
        map.put("insertedIndicesSecretKey", insertedIndices_secretKey);
        map.put("charListReqId",charListReqId);
        map.put("insertedIndicesReqId",insertedIndices_reqId);
        return "js/secrypt_model";
    }

    /**
     * 密钥是按照时间过期的，半小时内有效，配合注解 @EncryptDecryptTime 一起使用
     *
     * @param response
     * @param map
     * @return
     */
    @ApiOperation("普通接口加密模块")
    @IsSecurity(isSecurity = false)
    @GetMapping(value = "/s-secrypt-script.js", produces = "application/javascript")
    public String dynamicSScript(HttpServletResponse response, Map<String,Object> map){
        response.setContentType("application/javascript;charset=UTF-8");
        String randomString = RandomStringGenerator.generateRandomString(100); // 生成长度为 20 的随机字符串
        char[] randomCharArray = RandomStringGenerator.convertStringToCharArray(randomString);
        String sessionId=secretKeyComponent.getSessionId(); //获取随机会话id
        String secretKey= secretKeyComponent.getSecretKey(sessionId); //获取随机秘钥
        String sessionIdStr=sessionId;
        secretKey=Base64.getEncoder().encodeToString(secretKey.getBytes(StandardCharsets.UTF_8));
        sessionId=Base64.getEncoder().encodeToString(sessionId.getBytes(StandardCharsets.UTF_8));
        // 记录插入的下标
        List<Integer> insertedIndices_secretKey = new ArrayList<>();
        char[] newArraySecretKey = RandomStringGenerator.insertStringRandomly(randomCharArray, secretKey, insertedIndices_secretKey);
        List<Character> charListSecretKey = new java.util.ArrayList<>();
        for (char c : newArraySecretKey) {
            charListSecretKey.add(c);
        }
        List<Integer> insertedIndices_sessionId = new ArrayList<>();
        char[] newArraySessionId = RandomStringGenerator.insertStringRandomly(randomCharArray, sessionId, insertedIndices_sessionId);
        List<Character> charListSessionId = new java.util.ArrayList<>();
        for (char c : newArraySessionId) {
            charListSessionId.add(c);
        }
        //生成请求id,防止重复请求
        String reqId=String.valueOf(RandomNumber.generateRandomNumber(8))+String.valueOf(RandomNumber.generateRandomNumber(8));
       //10s以内不用重新请求
        sysCacheServer.put(reqId+"_time",sessionIdStr,1000 * 60 * 30 );
        reqId=Base64.getEncoder().encodeToString(reqId.getBytes(StandardCharsets.UTF_8));
        List<Integer> insertedIndices_reqId = new ArrayList<>();
        char[] newArrayReqId = RandomStringGenerator.insertStringRandomly(randomCharArray, reqId, insertedIndices_reqId);
        List<Character> charListReqId = new java.util.ArrayList<>();
        for (char c : newArrayReqId) {
            charListReqId.add(c);
        }
        map.put("isDecrypt",true);
        map.put("charListSecretKey", charListSecretKey);
        map.put("insertedIndicesSecretKey", insertedIndices_secretKey);
        map.put("charListReqId",charListReqId);
        map.put("insertedIndicesReqId",insertedIndices_reqId);
        return "js/secrypt_s_model";
    }

    @Autowired
    private SysUserTokenService sysUserTokenService;

    @ApiOperation("安全接口加密模块，需要登录")
    @GetMapping(value = "/t-secrypt-script.js", produces = "application/javascript")
    public String dynamicTScript(HttpServletRequest request,
                                 HttpServletResponse response, Map<String,Object> map){
        response.setContentType("application/javascript;charset=UTF-8");
        Cookie cookie= CookieUtils.getCookieByName(request.getCookies(),"sessionId");
        String oldSessionId="";
        if(cookie!=null){
            oldSessionId=cookie.getValue();
        }
        String randomString = RandomStringGenerator.generateRandomString(100); // 生成长度为 20 的随机字符串
        char[] randomCharArray = RandomStringGenerator.convertStringToCharArray(randomString);
        String sessionId=secretKeyComponent.getSessionId(); //获取随机会话id
        String secretKey= secretKeyComponent.getSecretKey(sessionId); //获取随机秘钥
        String sessionIdStr=sessionId;
        secretKey=Base64.getEncoder().encodeToString(secretKey.getBytes(StandardCharsets.UTF_8));
        sessionId=Base64.getEncoder().encodeToString(sessionId.getBytes(StandardCharsets.UTF_8));
        // 记录插入的下标
        List<Integer> insertedIndices_secretKey = new ArrayList<>();
        char[] newArraySecretKey = RandomStringGenerator.insertStringRandomly(randomCharArray, secretKey, insertedIndices_secretKey);
        List<Character> charListSecretKey = new java.util.ArrayList<>();
        for (char c : newArraySecretKey) {
            charListSecretKey.add(c);
        }
        List<Integer> insertedIndices_sessionId = new ArrayList<>();
        char[] newArraySessionId = RandomStringGenerator.insertStringRandomly(randomCharArray, sessionId, insertedIndices_sessionId);
        List<Character> charListSessionId = new java.util.ArrayList<>();
        for (char c : newArraySessionId) {
            charListSessionId.add(c);
        }
        //生成请求id,防止重复请求
        String reqId=sysUserTokenService.getSessionId();
        if(StringUtils.isNotBlank(oldSessionId)){
            SysCache sysCache =sysCacheServer.get(oldSessionId);
            if(sysCache!=null){
                sysCacheServer.put(reqId,sysCache.getValue());
                sysCacheServer.remove(oldSessionId,10);
            }
        }
        reqId=Base64.getEncoder().encodeToString(reqId.getBytes(StandardCharsets.UTF_8));
        List<Integer> insertedIndices_reqId = new ArrayList<>();
        char[] newArrayReqId = RandomStringGenerator.insertStringRandomly(randomCharArray, reqId, insertedIndices_reqId);
        List<Character> charListReqId = new java.util.ArrayList<>();
        for (char c : newArrayReqId) {
            charListReqId.add(c);
        }
        map.put("charListSecretKey", charListSecretKey);
        map.put("insertedIndicesSecretKey", insertedIndices_secretKey);
        map.put("charListReqId",charListReqId);
        map.put("insertedIndicesReqId",insertedIndices_reqId);
        return "js/secrypt_token_model";
    }
}
